

package cn.shengchao.controler.user;

import cn.dev33.satoken.annotation.SaIgnore;
import cn.hutool.core.util.StrUtil;
import cn.shengchao.examstar.distribute.infrastrure.po.DistributeNodeInfo;
import cn.shengchao.examstar.distribute.infrastrure.service.DistributeNodeInfoService;
import cn.shengchao.examstar.rpc.distribute.DistributeUserInviteApi;
import cn.shengchao.examstar.rpc.distribute.cs.UserCs;
import cn.shengchao.examstar.rpc.distribute.dto.UserInviteDto;
import cn.shengchao.examstar.rpc.distribute.enums.DistributeSaleRoleEnum;
import cn.shengchao.examstar.share.domain.entity.ShareLink;
import cn.shengchao.examstar.share.ohs.local.appservice.ShareAppService;
import cn.shengchao.examstart.user.ohs.local.appservices.UserAppService;
import cn.shengchao.examstart.user.ohs.local.messages.LoginValue;
import cn.shengchao.examstart.user.ohs.local.messages.SaveUserPreference;
import cn.shengchao.examstart.user.ohs.local.messages.UserInfoDto;
import cn.shengchao.examstart.user.ohs.local.messages.UserPreferenceDto;
import cn.shengchao.util.helper.LoginHelper;
import com.google.common.collect.Maps;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.tags.Tag;
import lombok.extern.slf4j.Slf4j;
import me.chanjar.weixin.common.error.WxErrorException;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.web.bind.annotation.*;
import top.continew.admin.common.model.dto.LoginUser;
import top.continew.starter.core.exception.BaseException;
import top.continew.starter.core.validation.CheckUtils;

import java.util.List;
import java.util.Map;
import java.util.Optional;

@Tag(name = "用户")
@Slf4j
@RestController
@CrossOrigin("${project.cross-origin}")
@RequestMapping("/api/${project.version}/user")
public class UserController {

    @Autowired
    private UserAppService userAppService;

    @Autowired
    private ShareAppService shareAppService;

    @Autowired
    private DistributeUserInviteApi distributeUserInviteApi;

    @Autowired
    private DistributeNodeInfoService distributeNodeInfoService;

    @Value("${spring.profiles.active}")
    private String env;

    @SaIgnore
    @GetMapping("{phone}/wxLoginSimulate")
    @Operation(summary = "微信么模拟登录", description = "微信登录")
    public LoginValue wxLoginSimulate(@PathVariable String phone) {
        LoginUser loginUser = userAppService.simplePhoneWxLogin(phone);
        if (loginUser == null) {
            throw new BaseException("微信模拟登录错误");
        }
        if (loginUser.getId() == null) {
            return LoginValue.notBindPhone(LoginHelper.login(loginUser));
        }
        if (distributeUserInviteApi.getUserInviteRecord(loginUser.getId()) == null) {
            UserInviteDto userInviteDto = new UserInviteDto();
            userInviteDto.setUserId(loginUser.getId());
            userInviteDto.setInviteUserId(UserCs.PLATFORM_USER_ID);
            distributeUserInviteApi.userInviteDistributeRecordIn(userInviteDto);
        }
        return LoginValue.of(loginUser.getNickname(), LoginHelper.login(loginUser), loginUser.getAvatar());
    }

    @SaIgnore
    @GetMapping("{appid}/wxLogin")
    @Operation(summary = "微信登录", description = "微信登录")
    public LoginValue wxLogin(@PathVariable String appid, @RequestParam String jsCode) {
        try {
            LoginUser loginUser = null;
            if (env.equals("xwq")) {
                loginUser = userAppService.simpleWxLogin(appid, jsCode);
            } else {
                loginUser = userAppService.wxLogin(appid, jsCode);
            }
            if (loginUser.getId() == null) {
                return LoginValue.notBindPhone(LoginHelper.login(loginUser));
            }
            return LoginValue.of(loginUser.getNickname(), LoginHelper.login(loginUser), loginUser.getAvatar());
        } catch (WxErrorException wxErrorException) {
            log.error("微信登录失败,appid:{},jsCode:{},error:{}", appid, jsCode, wxErrorException.getMessage());
            CheckUtils.throwIfNull(null, "微信登录失败");
            return LoginValue.notBindPhone(null);
        }
    }

    @SaIgnore
    @GetMapping("{appid}/phoneLogin")
    @Operation(summary = "短信登录", description = "微信登录")
    public LoginValue phoneLogin(@PathVariable String appid, @RequestParam String phone, @RequestParam String code, @RequestParam String shareCode) {
        LoginUser loginUser;
        loginUser = userAppService.phoneLogin(appid, phone, code);
        if (loginUser.getId() == null) {
            return LoginValue.notBindPhone(LoginHelper.login(loginUser));
        }
        //绑定用户
        if (StrUtil.isNotBlank(shareCode)) {
            Optional<ShareLink> shareLinkOptional = shareAppService.getShareInfo(shareCode);
            if (shareLinkOptional.isPresent()) {
                shareAppService.clickShareLink(loginUser.getId(), shareCode);
                UserInviteDto userInviteDto = new UserInviteDto();
                userInviteDto.setUserId(loginUser.getId());
                userInviteDto.setInviteUserId(shareLinkOptional.get().getShareUser().getId());
                distributeUserInviteApi.userInviteDistributeRecordIn(userInviteDto);
                return LoginValue.of(loginUser.getNickname(), LoginHelper.login(loginUser), loginUser.getAvatar());
            }
        }
        UserInviteDto userInviteDto = new UserInviteDto();
        userInviteDto.setUserId(loginUser.getId());
        userInviteDto.setInviteUserId(0L);
        distributeUserInviteApi.userInviteDistributeRecordIn(userInviteDto);
        return LoginValue.of(loginUser.getNickname(), LoginHelper.login(loginUser), loginUser.getAvatar());
    }

    @Operation(summary = "微信绑定手机号", description = "微信登录")
    @GetMapping("{appid}/bindPhone")
    public LoginValue bindPhone(@PathVariable String appid, @RequestParam String code, @RequestParam String shareCode) {
        try {
            //注册
            String openId = LoginHelper.getLoginUser().getOpenId();
            LoginUser loginUser = userAppService.bindPhone(appid, code, openId);
            LoginHelper.updateLoginUser(loginUser, LoginHelper.login(loginUser));
            //绑定用户
            if (StrUtil.isNotBlank(shareCode)) {
                Optional<ShareLink> shareLinkOptional = shareAppService.getShareInfo(shareCode);
                if (shareLinkOptional.isPresent()) {
                    shareAppService.clickShareLink(loginUser.getId(), shareCode);
                    UserInviteDto userInviteDto = new UserInviteDto();
                    userInviteDto.setUserId(loginUser.getId());
                    userInviteDto.setInviteUserId(shareLinkOptional.get().getShareUser().getId());
                    distributeUserInviteApi.userInviteDistributeRecordIn(userInviteDto);
                    return LoginValue.of(loginUser.getNickname(), LoginHelper.login(loginUser), loginUser.getAvatar());
                }
            }
            UserInviteDto userInviteDto = new UserInviteDto();
            userInviteDto.setUserId(loginUser.getId());
            userInviteDto.setInviteUserId(0L);
            distributeUserInviteApi.userInviteDistributeRecordIn(userInviteDto);
            return LoginValue.of(loginUser.getNickname(), LoginHelper.login(loginUser), loginUser.getAvatar());
        } catch (WxErrorException wxErrorException) {
            log.error("微信手机号绑定失败,appid:{},jsCode:{},error:{}", appid, code, wxErrorException.getMessage());
            CheckUtils.throwIfNull(null, "微信手机号绑定失败");
            return LoginValue.notBindPhone(null);
        }
    }

    @Operation(summary = "更新用户信息", description = "更新用户信息")
    @PostMapping("userInfo")
    public void setUserInfo(@RequestBody UserInfoDto userInfoReq) {
        userAppService.setUserInfo(userInfoReq, LoginHelper.getUserId());
    }

    @Operation(summary = "获取用户信息", description = "获取用户信息")
    @GetMapping("userInfo")
    public UserInfoDto getUserInfo() {
        return userAppService.getUserInfo(LoginHelper.getUserId());
    }

    @Operation(summary = "获取用户角色", description = "获取用户角色")
    @GetMapping("userRole")
    public Map.Entry<String, List<String>> getUserRole() {
        DistributeNodeInfo distributeNodeInfo = distributeNodeInfoService.getDistributeNodeInfoInCode(LoginHelper.getUserId(),
                List.of(DistributeSaleRoleEnum.ROLE_DSPD, DistributeSaleRoleEnum.ROLE_SLMB, DistributeSaleRoleEnum.ROLE_MKMG, DistributeSaleRoleEnum.ROLE_DSPD_EMP));
        if (distributeNodeInfo != null) {
            return Maps.immutableEntry("role", List.of(distributeNodeInfo.getDistributeRoleCode()));
        } else {
            return Maps.immutableEntry("role", List.of());
        }
    }

    @Operation(summary = "获取用户偏好", description = "获取用户偏好")
    @GetMapping("preference")
    public UserPreferenceDto getUserPreference() {
        return userAppService.getUserPreference(LoginHelper.getUserId());
    }

    @Operation(summary = "添加用户偏好", description = "添加用户偏好")
    @PostMapping("preference")
    public void addUserPreference(@RequestBody SaveUserPreference saveUserPreference) {
        LoginUser loginUser = LoginHelper.getLoginUser();
        userAppService.saveUserPreference(saveUserPreference, loginUser.getId());
    }

}
